package com.songlanyun.modules.supplychainmessage.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.songlanyun.common.annotation.AuthIgnore;
import com.songlanyun.common.supplychainapi.config.SupplyChaiProperties;
import com.songlanyun.common.utils.R;
import com.songlanyun.common.utils.StatusMsgEnum;
import com.songlanyun.modules.supplychainmessage.service.SupplyChainMessageService;
import com.songlanyun.modules.user.controller.AbstractController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 消息回调
 *
 * @author lijiahe 2022-02-25
 */
@Slf4j
@RestController
@RequestMapping("admin/supplychain/message")
public class SupplyChainMessageController extends AbstractController {

    @Autowired
    private SupplyChainMessageService supplyChainMessageService;

    @Autowired
    private SupplyChaiProperties supplyChaiProperties;

    /**
     * 回调
     *
     * @param params
     * @return
     */
    @AuthIgnore
    @PostMapping("/callback")
    public Map<String, Object> callback(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        log.info("----------------第三方回调开始");

        String sign = request.getHeader("sign");
        log.info("----------------签名：{}", sign);

        Map<String, Object> map = new HashMap<>();

        // TODO 验签
        if (!verifySign(sign, params)) {
//            return R.error("验签失败");
            map.put("code", -1);
            return map;
        }

        if (supplyChainMessageService.callback(params)) {
            map.put("code", 1);
        } else {
            map.put("code", -1);
        }
        return map;
    }

    /**
     * 检验签名
     *
     * @param sign
     * @param params
     * @return
     */
    private boolean verifySign(String sign, Map<String, Object> params) {
        if (StringUtils.isBlank(sign) || ObjectUtil.isNull(params)) {
            return false;
        }

//        签名计算规则
//        1.将回调的json后拼接secretKey
//        例如回调参数如下：
//        {"app_id":1,"data":{"goodsIds":[35137323]},"id":"20220726183234895644000545","push_time":1658831554895,"times":1,"type":"goods.on.sale"}
        String jsonParams = JSON.toJSONString(params);

//        2. 拼接secretKey
//        例：
//        {"app_id":1,"data":{"goodsIds":[35137323]},"id":"20220726183234895644000545","push_time":1658831554895,"times":1,"type":"goods.on.sale"}123stbz456
        String data = jsonParams + supplyChaiProperties.getAppSecret();

//        3.对上一步结果进行sha1加密
//        例：
//        621c0815f654fea5ea0091409101c57d2c555b10
        String sha1Data = DigestUtil.sha1Hex(data);

//        4.对上一步结果进行md5加密，得到32进制字符串
//        例：
//        a8d9ea079a8f034736114967f7b410e4
        String md5Data = DigestUtil.md5Hex(sha1Data);

//        5.将上一步结果转为大写
//        例：
//        A8D9EA079A8F034736114967F7B410E4
        String signData = md5Data.toUpperCase();
        log.info("----------------加密后数据：{}", signData);
        if (sign.equals(signData)) {
            log.info("----------------验签通过");
            return true;
        } else {
            log.error("----------------验签失败");
            return false;
        }
    }

}
